--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
docs/agents/overview.md 63f836b03d64eac4fa716b2ada23ab565c2b455e (63f836b0) Text, 18.02 KB
Tc9d1d9# MeshChatX agent overview
Project brief for automated agents and contributors.
Conventions and task skills live under Ta5d6ff`docs/agents/`. This file is the durable source of truth for architecture and invariants.
Tc9d1d9## What this project is
Reticulum MeshChatX is a local-first mesh communications client on the Reticulum Network Stack.
It is an independent fork of Reticulum MeshChat and is not affiliated with the upstream project.
Core protocols:
Tff7b72- **Reticulum (RNS)** - identities, paths, interfaces, encrypted transport
Tff7b72- **LXMF** - messaging, attachments, propagation nodes
Tff7b72- **LXST** - audio calls and telephony
One Python process owns the web server, Reticulum stack, and per-identity managers.
The Vue frontend is static assets served from Ta5d6ff`meshchatx/public/` after a Vite build.
Electron and Android wrap the same backend.
Website: [Tff7b72meshchatx.com](Te6edf3https://meshchatx.com)
Source: [Tff7b72github.com/Quad4-Software/MeshChatX](Te6edf3https://github.com/Quad4-Software/MeshChatX)
Tc9d1d9## Design goals (do not violate casually)
Tff7b72- Local-first. Works on desktop, mobile, containers, and SBCs.
Tff7b72- Preserve Reticulum / LXMF / LXST semantics while improving UX and ops tooling.
Tff7b72- Multiple identities in one process without cross-identity data leakage.
Tff7b72- Python backend and Vue frontend independently testable.
Tff7b72- Predictable SQLite behaviour in constrained environments.
Tff7b72- Prefer identity-scoped state, explicit migrations, and narrowly declared plugin permissions.
Tc9d1d9## Reticulum Zen gates (mesh work)
MeshChatX sits on Reticulum. Agents must not invent cloud-era or IP-era designs for mesh features.
Tff7b72- Philosophy: [Tff7b72Zen of Reticulum](Te6edf3https://reticulum.network/manual/zen.html)
Tff7b72- Conventions: Ta5d6ff`docs/agents/conventions/reticulum-zen.md`
Tff7b72- Checklist skill: Ta5d6ff`docs/agents/skills/reticulum-design-gates/SKILL.md`
Tff7b72- Cursor always-on rule: Ta5d6ff`.cursor/rules/reticulum-zen-gates.mdc`
Short form: no mandatory cloud center, address destination hashes, assume hostile links, design for scarcity and delay, keep code transport-agnostic, keep identity state scoped.
Tc9d1d9## Runtime shape
Ta5d6ff```
Browser / Electron / Android WebView
|
| HTTPS REST /api/v1/* and WSS /ws (+ /ws/telephone/audio)
v
ReticulumMeshChat (meshchatx/meshchat.py)
|
+-- HTTP routes and static public/
+-- WebSocket event fan-out
+-- IdentityContext (active identity only)
| +-- SQLite (database.db under identity storage)
| +-- LXMRouter and message managers
| +-- TelephoneManager (LXST)
| +-- Domain managers (map, docs, RRC, bots, ...)
+-- Shared Reticulum instance (default ~/.reticulum)
```
Critical lifecycle facts:
Tff7b72- HTTP can bind before RNS/identity finish starting. Ta5d6ff`/api/v1/status` reports Ta5d6ff`starting` / Ta5d6ff`ok` / Ta5d6ff`failed` with Ta5d6ff`stage` and Ta5d6ff`network_ready`.
Tff7b72- CLI one-shots (Ta5d6ff`--self-check`, backup/restore helpers) still initialize synchronously.
Tff7b72- Switching identities tears down the old Ta5d6ff`IdentityContext` and loads another. Do not stash identity-specific state in process globals.
Tc9d1d9## Repository layout
| Path | Role |
| ------------------------- | ----------------------------------------- |
| Ta5d6ff`meshchatx/meshchat.py` | Orchestration, HTTP/WS routes, CLI |
| Ta5d6ff`meshchatx/src/backend/` | Managers, DB, security, Landlock, plugins |
| Ta5d6ff`meshchatx/src/frontend/` | Vue 3 UI, locales, registries, helpers |
| Ta5d6ff`meshchatx/public/` | Built frontend assets consumed at runtime |
| Ta5d6ff`electron/` | Desktop shell around local HTTPS backend |
| Ta5d6ff`android/` | WebView + Chaquopy Python bridge |
| Ta5d6ff`tests/backend/` | pytest |
| Ta5d6ff`tests/frontend/` | vitest |
| Ta5d6ff`tests/e2e/` | Playwright |
| Ta5d6ff`docs/en/` | In-app / shipped English docs |
| Ta5d6ff`vendor/` | Vendored deps (for example LXMFy) |
| Ta5d6ff`Taskfile.yml` | Preferred command entrypoints |
| Ta5d6ff`docs/agents/` | Agent guidance (this tree) |
| Ta5d6ff`AGENTS.md` | Short pointer to Ta5d6ff`docs/agents/` |
Business rules belong in backend managers under Ta5d6ff`meshchatx/src/backend/`.
Keep Ta5d6ff`meshchat.py` focused on transport and lifecycle when possible.
Tc9d1d9## Tooling and versions
Tff7b72- Python Ta5d6ff`>=3.11` (CI commonly runs 3.14)
Tff7b72- Node.js Ta5d6ff`>=24`, pnpm from Ta5d6ff`package.json` Ta5d6ff`packageManager`
Tff7b72- UV for Python deps
Tff7b72- Task for common workflows
Prefer Task targets over inventing one-off scripts:
Ta5d6ff```Ta5d6ffbash
task install
task format
task lint
task test:quick
task test:eect
task test:lv:l0
task test:backend
task test:frontend
task test:e2e
task run
task dev
Ta5d6ff```
Optional RNS/rngit tooling (requires mesh reachability, can sometimes be significantly slower than PyPI):
Ta5d6ff```Ta5d6ffbash
task deps:backend:rns
task docs:rns
Ta5d6ff```
Useful focused commands:
Ta5d6ff```Ta5d6ffbash
uv run pytest tests/backend/test_<name>.py -q --tbTff7b72=short
pnpm Tffa657exec vitest run tests/frontend/<Name>.test.js
pnpm Tffa657exec eslint <file> --fix
uv run python -m meshchatx.meshchat --self-check
Ta5d6ff```
Tc9d1d9## Storage and identity model
Default storage root: Ta5d6ff`./storage` (override with Ta5d6ff`--storage-dir` / Ta5d6ff`MESHCHAT_STORAGE_DIR`).
Android may prefer external app files storage.
Per identity:
Ta5d6ff```
storage/identities/<identity_hash>/
identity # private key bytes
metadata.json # display name, icon, cached addresses
database.db # SQLite (WAL files may exist)
database-backups/ # zip backups
snapshots/ # named snapshots
ssl/ # per-identity cert/key when using defaults
... # LXMF dirs, caches, sqlite-tmp, etc.
```
Shared outside identity storage:
Tff7b72- Reticulum config: Ta5d6ff`~/.reticulum` by default (Ta5d6ff`--reticulum-config-dir` / Ta5d6ff`MESHCHAT_RETICULUM_CONFIG_DIR`)
Tff7b72- Interfaces and transport settings live with Reticulum, not only in the identity DB
Tc9d1d9### Identity key restore vs database restore
These are different operations. Do not conflate them in UI copy or code paths.
| Goal | Where | Artifact / API |
| --------------------------------------------- | ---------------------------------- | ------------------------------------------------------ |
| Restore private key only | Tutorial step 2, Identities import | Ta5d6ff`POST /api/v1/identity/restore` |
| Restore LXMF history, settings, identity tree | About → Restore from File, CLI | Ta5d6ff`POST /api/v1/database/restore`, Ta5d6ff`--restore-db` Ta5d6ff`.zip` |
Identity export download should use a real extension such as Ta5d6ff`identity.bin`.
File pickers for keys should accept Ta5d6ff`.bin`, Ta5d6ff`.key`, Ta5d6ff`.identity`, Ta5d6ff`application/octet-stream`, and Ta5d6ff`*/*`.
Database restore pickers stay Ta5d6ff`.zip`.
Tc9d1d9## Persistence rules
Tff7b72- Engine: SQLite with explicit SQL and versioned migrations (no ORM).
Tff7b72- Schema changes go through migrations in the database schema layer.
Tff7b72- Backups and snapshots are first-class recovery tools. Prefer restore APIs over hand-editing DB files.
Tff7b72- Conversation list / sidebar queries must stay slim. Truncate content previews. Derive attachment flags in SQL. Do not ship multi-MB Ta5d6ff`fields` blobs in list endpoints.
Tff7b72- Worker-thread DB connections must apply the same pragmas as the main connection via Ta5d6ff`DatabaseProvider` (especially Ta5d6ff`temp_store`).
Tc9d1d9## Landlock and Linux sandboxing
On Linux, MeshChatX can apply a Landlock filesystem sandbox after startup.
Control with Ta5d6ff`MESHCHAT_LANDLOCK` (Ta5d6ff`1` force on, Ta5d6ff`0` force off, unset = auto when kernel supports it).
Critical SQLite interaction:
Tff7b72- Under Landlock, Ta5d6ff`PRAGMA temp_store=FILE` can break complex conversation queries with Ta5d6ff`unable to open database file`.
Tff7b72- Default worker connections to Ta5d6ff`temp_store=MEMORY`.
Tff7b72- Memory-pressure mode may shrink cache/mmap. While Landlock is active, keep MEMORY temp.
Tff7b72- Without Landlock, FILE temp plus a storage-local Ta5d6ff`sqlite-tmp` TMPDIR is acceptable.
Landlock apply is process-wide and one-shot. Tests that enable it must run in a subprocess.
Also see Ta5d6ff`docs/en/platform-guides/linux-sandbox.md` for Firejail / Bubblewrap host examples.
Tc9d1d9## Security model (critical)
Defaults aim at secure local operation:
Tff7b72- HTTPS and WSS on by default (self-signed certs per identity when custom PEMs absent)
Tff7b72- Optional HTTP auth (Ta5d6ff`--auth` / Ta5d6ff`MESHCHAT_AUTH=true`)
Tff7b72- CSRF on mutating HTTP requests
Tff7b72- Encrypted session cookies
Tff7b72- CORS / CSP / defensive HTTP middleware
Tff7b72- Access-attempt logging and lockout when auth is enabled
Tff7b72- IP allowlisting available via app security settings
Tff7b72- Privacy mode can block outbound clearnet HTTP from app features (does not stop Reticulum mesh traffic)
Do not recommend exposing MeshChatX directly on the public internet without extra hardening.
Prefer bind Ta5d6ff`127.0.0.1`, HTTPS, and auth if other local users share the host.
Sensitive config changes (for example auth enable / password hash) must use CSRF-protected HTTP endpoints, not unrestricted WebSocket mutators.
Password reset: Ta5d6ff`--reset-password` or Ta5d6ff`MESHCHAT_RESET_PASSWORD=true` clears the stored hash so a new password can be set in the UI.
Tc9d1d9### Plugins
Plugins are powerful and partially sandboxed. Treat install/enable paths as security-sensitive.
Tff7b72- Frontend plugins run in Workers with capability grants
Tff7b72- Backend WASM plugins use wasmtime with fuel / capability gates
Tff7b72- Backend Python plugins and Sideband loaders are higher risk and permission-gated / danger-switched
Tff7b72- Invalid RSG signatures hard-block install
Tff7b72- Tampered installed trees should disable as integrity failures
Tff7b72- Disable all plugins with Ta5d6ff`--disable-plugins` / Ta5d6ff`MESHCHAT_DISABLE_PLUGINS=true`
Tc9d1d9## HTTP and WebSocket surface
Tff7b72- REST under Ta5d6ff`/api/v1/*`
Tff7b72- Frontend uses Ta5d6ff`window.api` / Ta5d6ff`apiClient.js` with CSRF on mutating calls
Tff7b72- WebSocket Ta5d6ff`/ws` for live events (messages, identity switch, telephone, RRC, Nomad downloads, plugins, RNS link events)
Tff7b72- Typed WS handlers live in frontend registries (Ta5d6ff`wsEventRegistry` / Ta5d6ff`wsEventBridge`)
Tff7b72- Generic RNS Link API over WS (Ta5d6ff`rns.link.open|identify|request|send|close` and Ta5d6ff`rns.link.event`) for external tools and plugins. See Ta5d6ff`docs/en/rns-link-api.md`.
When identity/network is not ready, prefer **503** with a retryable message over opaque **500** for temporary DB/startup failures.
Tc9d1d9## Frontend conventions
Tff7b72- Vue 3 Options API is the dominant style. Match the file you edit.
Tff7b72- Routes are hash-based (for example Ta5d6ff`#/messages`).
Tff7b72- New top-level pages need: route in Ta5d6ff`main.js`, nav/tools entry when discoverable, i18n keys, tests.
Tff7b72- User-visible strings go through locale files (Ta5d6ff`meshchatx/src/frontend/locales/en.json` at minimum).
Tff7b72- User-visible action outcomes use Ta5d6ff`ToastUtils`.
Tff7b72- Do not use Ta5d6ff`_`-prefixed keys in Vue Ta5d6ff`data()` (Ta5d6ff`vue/no-reserved-keys`).
Tff7b72- Contribution registries drive nav, tools, commands, settings sections, and WS events. Prefer extending registries over hardcoding one-off shell wiring.
Tc9d1d9## Android specifics
Tff7b72- UI is a WebView. Backend runs via Chaquopy.
Tff7b72- File chooser: bare extension tokens like Ta5d6ff`.identity` are not valid MIME types for Ta5d6ff`Intent.EXTRA_MIME_TYPES`. Map them to Ta5d6ff`application/octet-stream` / Ta5d6ff`*/*`.
Tff7b72- Set multi-select only when the WebView chooser mode requests it.
Tff7b72- Storage setup (internal vs external) can create a fresh-looking install if the user picks a different location than previous data.
Tff7b72- External http(s) links should open in the system browser, not navigate the WebView away from the app.
Tc9d1d9## Important environment variables and flags
Common overrides (CLI flags usually mirror these):
| Variable / flag | Purpose |
| ---------------------------------------------------------- | ------------------------------------------------ |
| Ta5d6ff`MESHCHAT_HOST` / Ta5d6ff`--host` | Bind address (default Ta5d6ff`127.0.0.1`) |
| Ta5d6ff`MESHCHAT_PORT` / Ta5d6ff`--port` | Bind port (default Ta5d6ff`8000`) |
| Ta5d6ff`MESHCHAT_HEADLESS` / Ta5d6ff`--headless` | Do not auto-launch a browser |
| Ta5d6ff`MESHCHAT_STORAGE_DIR` / Ta5d6ff`--storage-dir` | App storage root |
| Ta5d6ff`MESHCHAT_RETICULUM_CONFIG_DIR` / Ta5d6ff`--reticulum-config-dir` | Reticulum config dir |
| Ta5d6ff`MESHCHAT_PUBLIC_DIR` / Ta5d6ff`--public-dir` | Frontend assets dir |
| Ta5d6ff`MESHCHAT_AUTH` / Ta5d6ff`--auth` | Enable web auth |
| Ta5d6ff`MESHCHAT_NO_HTTPS` / Ta5d6ff`--no-https` | HTTP instead of HTTPS |
| Ta5d6ff`MESHCHAT_SSL_CERT` + Ta5d6ff`MESHCHAT_SSL_KEY` | Custom TLS PEM pair (both required) |
| Ta5d6ff`MESHCHAT_IDENTITY_FILE` / Ta5d6ff`BASE32` / Ta5d6ff`BASE64` | Seed identity from key material |
| Ta5d6ff`MESHCHAT_AUTO_RECOVER` / Ta5d6ff`--auto-recover` | Attempt DB recovery on startup |
| Ta5d6ff`MESHCHAT_EMERGENCY` / Ta5d6ff`--emergency` | Emergency mode (limited operation) |
| Ta5d6ff`MESHCHAT_RESET_PASSWORD` / Ta5d6ff`--reset-password` | Clear password hash |
| Ta5d6ff`MESHCHAT_DISABLE_PLUGINS` / Ta5d6ff`--disable-plugins` | Disable plugin system |
| Ta5d6ff`MESHCHAT_LANDLOCK` | Ta5d6ff`1` / Ta5d6ff`0` / unset auto |
| Ta5d6ff`MESHCHAT_SELF_CHECK` / Ta5d6ff`--self-check` | Run diagnostics and exit |
| Ta5d6ff`MESHCHAT_MEMORY_DIAG` / Ta5d6ff`--memory-diag` | tracemalloc diagnostics |
| Ta5d6ff`MESHCHAT_DISABLE_CSRF` | Dangerous. Tests/dev only |
| Ta5d6ff`MESHCHAT_SKIP_STORAGE_LOCK` | Dangerous. Avoid overlapping instances carefully |
| Ta5d6ff`MESHCHAT_RNS_LOG_LEVEL` | RNS log verbosity |
Restore helpers:
Ta5d6ff```Ta5d6ffbash
meshchatx --restore-db /path/to/backup.zip
Ta5d6ff```
Tc9d1d9## Testing expectations
Tff7b72- Backend change → update Ta5d6ff`tests/backend/`
Tff7b72- Frontend change → update Ta5d6ff`tests/frontend/`
Tff7b72- API contract / route list fixtures may need updates when routes change
Tff7b72- Prefer focused suites in agent loops. Full Ta5d6ff`task test` is heavy.
Tff7b72- Avoid piping long pytest runs through Ta5d6ff`| tail` in automation shells (can hang the harness).
Tff7b72- Landlock-enable tests must use a subprocess.
Tff7b72- Long-running soak / some notification suites can hang. Use timeouts and isolate them unless explicitly requested.
Tff7b72- Self-check and CI matrices cover cross-platform boot, storage lock fallbacks, and critical HTTP/WS probes. Do not weaken those without cause.
Tc9d1d9## Licensing and contributions
Tff7b72- Prefer existing per-file SPDX headers. Project-owned files are typically Ta5d6ff`0BSD`.
Tff7b72- Upstream-derived files may be MIT or dual-marked. Preserve obligations.
Tff7b72- Patch-oriented contribution flow is documented in Ta5d6ff`CONTRIBUTING.md` (LXMF patch submission is first-class for some contributors).
Tff7b72- Generative AI policy in Ta5d6ff`CONTRIBUTING.md` requires disclosure and human review. Do not submit unreviewed bulk-generated churn.
Tc9d1d9## Agent hard rules
Tff7b721. No emojis in code, markdown, or docs you write for this repo.
Tff7b722. No TODO / FIXME noise comments.
Tff7b723. No emdashes or semicolons in comments or docs you write.
Tff7b724. Do not create markdown docs unless asked (except agent guidance under Ta5d6ff`docs/agents/` when requested).
Tff7b725. Do not commit or push unless the user asks.
Tff7b726. Do not generate exploit PoCs, malware, or attack tooling.
Tff7b727. Prefer minimal diffs. Match nearby style.
Tff7b728. Do not invent install/run flows when Taskfile already covers them.
Tff7b729. Mesh-facing designs must pass Zen / architecture gates (Ta5d6ff`reticulum-zen.md` / Ta5d6ff`reticulum-design-gates`).
Tc9d1d9## High-risk change checklist
Before finishing work in these areas, verify the matching invariants:
Tff7b721. **Identity import / tutorial** - key-only vs zip restore copy is correct, picker accepts real exports, activate-on-finish / skip paths do not orphan imports.
Tff7b722. **Conversations / notifications DB** - slim queries, MEMORY temp under Landlock, 503 on retryable SQLite errors. Sidebar unread pills (messages, relay mentions, missed calls) stay in sync with read/viewed state. No header notification bell.
Tff7b723. **Auth / CSRF / WS config** - no new unauthenticated mutating surfaces, no sensitive settings over open WS mutators.
Tff7b724. **Plugins** - permissions declared, install preview/consent preserved, signatures/integrity not bypassed.
Tff7b725. **Android bridges** - MIME mapping, storage paths, and WebView navigation guards remain correct.
Tff7b726. **Identity switch** - no cross-identity leakage via caches, routers, or global singletons.
Tff7b727. **Migrations** - schema version bump and upgrade path tested.
Tc9d1d9## Where to read next
Tff7b72- Ta5d6ff`docs/agents/conventions/reticulum-zen.md` - Zen of Reticulum hard gates
Tff7b72- Ta5d6ff`docs/agents/skills/reticulum-design-gates/SKILL.md` - mesh design checklist
Tff7b72- Ta5d6ff`docs/en/architecture.md` - design and process overview
Tff7b72- Ta5d6ff`docs/en/identity-and-security.md` - identities, auth, privacy, backups
Tff7b72- Ta5d6ff`docs/en/getting-started.md` - UI map and first-run workflow
Tff7b72- Ta5d6ff`docs/en/rns-link-api.md` - generic RNS Link WebSocket API
Tff7b72- Ta5d6ff`docs/en/platform-guides/linux-sandbox.md` - Firejail / Bubblewrap
Tff7b72- Ta5d6ff`docs/en/messaging.md` - LXMF behaviour
Tff7b72- Ta5d6ff`CHANGELOG.md` - version-facing behaviour changes
Tff7b72- Ta5d6ff`CONTRIBUTING.md` - patch and AI disclosure policy
Tc9d1d9## Agent guidance index
Tff7b72- Ta5d6ff`docs/agents/README.md` - index of conventions and skills
Tff7b72- Ta5d6ff`docs/agents/conventions/` - surface-specific rules including Reticulum Zen
Tff7b72- Ta5d6ff`docs/agents/skills/` - focused workflows including reticulum-design-gates, pages, registries, identity restore/switch, Landlock/SQLite, migrations/backups, auth/CSRF/WS, plugins, RNS Link API, deferred startup, Electron packaging, Android bridge, and test loop
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────